import axios, { type AxiosRequestConfig } from 'axios';
import { ElLoading } from 'element-plus';
const pendingMap = new Map()//存储正在进行中的请求，用于避免重复请求用的

const LoadingInstance: {
  _target: any | null,
  _count: number,
} = {
  _target: null,
  _count: 0,
}

interface axiosCusConfig{
  repeat_request_cancel?:boolean,//是否开启重复请求取消，默认开启
  loading?:boolean//是否开启请求loading，默认不开启
}

function myAxios(axiosConfig: AxiosRequestConfig,customConfig?: axiosCusConfig,loadingOptions?:any) {
 
  const service = axios.create({
    baseURL: 'http://localhost:5215', // 设置统一的请求前缀
    timeout: 10000, // 设置统一的超时时长
  });

  //在用户传进来的自定义配置信息里加上一些默认值，如果用户没有传入自定义配置，则使用默认值
const customConfigExtend=Object.assign({
    repeat_request_cancel: true, // 是否开启重复请求取消
    loading: false, // 是否开启loading
}, customConfig || {})

service.interceptors.request.use(
    config => {
      removePending(config);//删除重复请求
      customConfigExtend.repeat_request_cancel && addPending(config);
      if (customConfigExtend.loading) {
          LoadingInstance._count++;
          if(LoadingInstance._count === 1) {
        
            LoadingInstance._target=ElLoading.service(loadingOptions);
          }
      }
      return config;
    },
    error => {
      return Promise.reject(error);
    }
  );

  service.interceptors.response.use(
    response => {
      removePending(response.config);
      customConfigExtend.loading && closeLoading(LoadingInstance);
      return response;
    },
    error => {
      error.config && removePending(error.config);
      return Promise.reject(error);
    }
  );



  return service(axiosConfig)
}

export default myAxios;




/**
 * 生成每个请求的唯一key
 */
function getPendingKey(config: AxiosRequestConfig) {
    let { data } = config
    const { url, method, params, headers } = config
    if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象
    return [
        url,
        method,
        headers && (headers as any).batoken ? (headers as any).batoken : '',
        headers && (headers as any)['ba-user-token'] ? (headers as any)['ba-user-token'] : '',
        JSON.stringify(params),
        JSON.stringify(data),
    ].join('&')
}

/**
 * 储存每个请求的唯一cancel回调, 以此为标识
 */
function addPending(config: AxiosRequestConfig) {
    const pendingKey = getPendingKey(config)
    config.cancelToken =
        config.cancelToken ||
        new axios.CancelToken((cancel) => {
            if (!pendingMap.has(pendingKey)) {
                pendingMap.set(pendingKey, cancel)
            }
        })
}


/**
 * 删除重复的请求
 * @param {*} config
 */
function removePending(config: AxiosRequestConfig) {
  const pendingKey = getPendingKey(config);
  if (pendingMap.has(pendingKey)) {
     const cancelToken = pendingMap.get(pendingKey);
     cancelToken(pendingKey);
     pendingMap.delete(pendingKey);
  }
}

/** 
 * * 关闭loading，
 */
function closeLoading(option:any) {
  if (LoadingInstance._count>0) LoadingInstance._count--;
  if(LoadingInstance._count===0){
    LoadingInstance._target?.close();
    LoadingInstance._target = null;
  }

}